// ZipParser.h : Declaration of the CZipParser

#pragma once
#include "resource.h"       // main symbols

#include "Version3.SharePoint_i.h"


#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif



// CZipParser

class ATL_NO_VTABLE CZipParser :
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<CZipParser, &CLSID_ZipParser>,
	public IZipParser,
	public IDispatchImpl<ISPDocumentParser, &__uuidof(ISPDocumentParser), &LIBID_Version3SharePointLib, /* wMajor = */ 1, /* wMinor = */ 0>
{
public:
	CZipParser()
	{
		m_pUnkMarshaler = NULL;
		m_OtherZipParser = NULL;
		m_OtherZipParserDLL = NULL;
		m_XMLConfiguration = NULL;
		m_AlwaysCallOtherZipParser = false;
		m_AlwaysReloadConfigXML = false;
	}

	DECLARE_REGISTRY_RESOURCEID(IDR_ZIPPARSER)


	BEGIN_COM_MAP(CZipParser)
		COM_INTERFACE_ENTRY(IZipParser)
		COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
		COM_INTERFACE_ENTRY(ISPDocumentParser)
	END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()
	DECLARE_GET_CONTROLLING_UNKNOWN()

	HRESULT FinalConstruct()
	{
		//CStringW consoleMessage;
		//consoleMessage.Format(_T("Please attach a debugger to the process %u and click OK"),::GetCurrentProcessId());
		//::MessageBoxW(NULL, consoleMessage.GetBuffer(), _T("SCORM PARSER"), MB_OK|MB_SERVICE_NOTIFICATION);

		HRESULT returnValue =  CoCreateFreeThreadedMarshaler(GetControllingUnknown(), &m_pUnkMarshaler.p);
		if(SUCCEEDED(returnValue))
		{
			m_ConfigurationXMLFilePath = GetConfigurationDocumentPath();
			m_XMLConfiguration = GetXMLDOMDocument(m_ConfigurationXMLFilePath);
			ReadConfiguration();
		}
		return returnValue;
	}

	void FinalRelease()
	{
		m_XMLConfiguration = NULL;
		m_pUnkMarshaler.Release();
	 	m_OtherZipParser.Release();
		if(NULL != m_OtherZipParserDLL)
		{
			::FreeLibrary(m_OtherZipParserDLL);
		}
	}


private:
	CComPtr<IUnknown> m_pUnkMarshaler;
	CComPtr<ISPDocumentParser> m_OtherZipParser;
	MSXML2::IXMLDOMDocument3Ptr m_XMLConfiguration;
	HMODULE	m_OtherZipParserDLL;
	CStringW m_MultiValueDelimiter;
	CStringW m_ConfigurationXMLFilePath;
	bool m_AlwaysCallOtherZipParser;
	bool m_AlwaysReloadConfigXML;

	void ReadConfiguration();
	void LoadOtherParser(CLSID classID);
	void LoadOtherParser(CLSID classID, CStringW dllPath);

	
	CStringW GetConfigurationDocumentPath();
	MSXML2::IXMLDOMDocument3Ptr GetXMLDOMDocument(CStringW filePath);
	MSXML2::IXMLDOMDocument3Ptr GetXMLDOMDocument(CHeapPtr<BYTE> memoryBuffer);

	void ParseXMLIntoPropertyBag(MSXML2::IXMLDOMDocument3Ptr propertyDoc,MSXML2::IXMLDOMNodePtr parserAttempt,IParserPropertyBag * pibag);
	void AddPropertyValuesToPropertyBagFromXPath(_bstr_t columnName,_bstr_t xpathExpression,CStringA multiValueDelimiter, MSXML2::IXMLDOMDocument3Ptr propertyDoc,IParserPropertyBag * pibag);
	void AddPropertyValuesToPropertyBag(CStringA propertyName,CStringA propertyValue,IParserPropertyBag * pibag);
	HRESULT ChainParse(ILockBytes * pilb,IParserPropertyBag * pibag, VARIANT_BOOL * pfChanged);
	
		 
public:
	STDMETHOD(Parse)( ILockBytes * pilb,  IParserPropertyBag * pibag,  VARIANT_BOOL * pfChanged);
	STDMETHOD(Demote)( ILockBytes * pilb,  IParserPropertyBag * pibag,  VARIANT_BOOL * pfChanged);
	STDMETHOD(ExtractThumbnail)( ILockBytes * pilb,  IStream * pistmThumbnail);

};

OBJECT_ENTRY_AUTO(__uuidof(ZipParser), CZipParser)
